<?php

    class database
    {
        /** host config*/
        public $HOST = "localhost";
        public $USERNAME = "root";
        public $PASSWORD = "";
        public $DATABASE = "sellcenter";
        public static $iCountQuerySPARQL = 0;
        public static $iCountNormalQuery = 0;

        public $db = null;
        public $sSql = '';
        /** check connect database*/
        public function connect()
        {
            $this->db = mysql_pconnect($this->HOST, $this->USERNAME, $this->PASSWORD);
            if(!$this->db)
            {
                echo "connect fail!";
                exit;
            }
            mysql_select_db($this->DATABASE);
            mysql_query("SET NAMES utf8");
        }

        /** FUNCTION execute($strQuery)
        *   Execute a query and return $result
        *   To get resources of $aResult make step
        *   if(mysql_num_rows($aResult))
        *   {
        *       echo "<table>";
        *       while($row = mysql_fetch_array($aResult))
        *       {
        *           echo "<tr>";
        *           echo "<td>".$row['product_id']."</td>";
        *           ....
        *           echo "</tr>";
        *       }
        *       echo "</table>";
        *   }
        */
        public function execute($strQuery)
        {
            database::$iCountNormalQuery++;
            $this->sSql = $strQuery;
            $this->connect();
            $aResult = mysql_query($strQuery, $this->db);
            if($aResult)
            {
                return $aResult;
            }
            return false;
        }

        /** FUNCTION getObject($strQuery)
        *   $oProduct = $oDatabase->getObject("select * from product");
        *   echo "<h1>ID: ".$oProduct->name."</h1>";
        */
        public function getObject($strQuery)
        {
            $aResult = $this->execute($strQuery);
            if(mysql_num_rows($aResult))
            {
                $aRow = mysql_fetch_object($aResult);
                return $aRow;
            }
            return null;
        }

        /** FUNCTION getListObject($strQuery, $bId = false)
        *   default function $bId = false, if $bId = true, return key with primary key
        *   $aListProduct = $oDatabase->getListObject("select * from product");
        *   foreach($aListProduct as $key => $oProduct)
        *   {
        *       echo "<h1>Key $key value $oProduct->name</h1>";
        *       .....
        *   }
        *   
        *   To get an object in list from id.
        *   print_r($aListProduct['2']);
        *   note above 2 is ID not index.
        *   example a product has id is 4 get it from list
        *   $aListproducts[4]
        */
        public function getListObject($strQuery, $bId = false, $bArray = false)
        {
            $aResult = $this->execute($strQuery);
            if(mysql_num_rows($aResult))
            {
                $aList = array();
                $sFieldId = mysql_fetch_field($aResult,0)->name;
                if(!$bArray)
                {
                    while($row = mysql_fetch_object($aResult))
                    {
                        eval('$sId = $row->'.$sFieldId.";");
                        if($bId)
                        {
                            $aList[$sId] = $row;
                        }
                        else
                        {
                            array_push($aList, $row);
                        }    
                    }
                }
                else
                {
                    while($row = mysql_fetch_array($aResult))
                    {
                        eval('$sId = $row["'.$sFieldId.'"];');
                        if($bId)
                        {
                            $aList[$sId] = $row;
                        }
                        else
                        {
                            array_push($aList, $row);
                        }    
                    }
                }
                return $aList;
            }
            return array();
        }

        /** FUNCTION  getValue($strQuery)
        *   return a value from query like number, string
        *   note result is string so to use it you must pass to int or ....
        *   $iTotal = $oDatabase->getValue("select * from product where product_id = 12");
        *   echo "<h1>Total: $iTotal</h1>";
        */
        public function getValue($strQuery)
        {
            $aResult = $this->execute($strQuery);
            if(mysql_num_rows($aResult))
            {
                $aRow = mysql_fetch_row($aResult);
                if($aRow)
                {
                    return $aRow[0];
                }
                return null;
            }
            return null;
        }
        /** FUNCTION add
        *   add row into table
        *   example
        *   $aProduct = array(
        *       'name' = 'iphone5',
        *       'total' = 32
        *   );
        *   $oDatabase->add('product', $aData);
        */
        public function add($sTable = '', $aData = array())
        {
            $sFiedl = '';
            $sValue = '';
            foreach($aData as $key => $value)
            {
                $sFiedl = $sFiedl."$key,";
                $sValue = $sValue."'$value',";
            }
            $sFiedl = trim($sFiedl , ',');
            $sValue = trim($sValue , ',');
            $sSql = "INSERT INTO $sTable($sFiedl) VALUES($sValue);";
            $result = $this->execute($sSql);
            if($result)
            {
                $iId = mysql_insert_id();
                if($iId)
                {
                    return $iId;
                }
                else
                {
                    return true;
                }
            }
            return false;
        }

        /** FUNCTION delete($sTable = '', $aCondition = array())
        *   delete row from table
        *   $aCondition = array(
        *       'id > 20' => AND
        *       'id < 30' => ''
        *   );
        *   $oDatabase->delete('product', $aCondition);
        */
        public function delete($sTable = '', $aCondition = array())
        {
            $sCondition = '';
            if(count($aCondition))
            {
                foreach($aCondition as $key => $value)
                {
                    $sCondition = $sCondition . "$key $value ";
                }
                $sSql = "DELETE FROM $sTable WHERE $sCondition";
            }
            else
            {
                $sSql = "DELETE FROM $sTable";
            }

            $result = $this->execute($sSql);
            return $result;
        }

        /** FUNCTION update($sTable = '', $aData = array(), $aCondition = array())
        *   update row in table
        *   $aCondition = array(
        *       'id> 20' => 'AND',
        *       'id < 10' => ''
        *   );
        *   $aData = array(
        *       'name' => 'trieu quang phuc',
        *       'total' => 3434
        *   );
        *   $oDatabase->update('product', $aData, $aCondition);
        */
        public function update($sTable = '', $aData = array(), $aCondition = array())
        {
            $sCondition = '';
            if(count($aCondition))
            {
                foreach($aCondition as $key => $value)
                {
                    $sCondition = $sCondition . "$key $value ";
                }
            }
            else
            {
                $sCondition = '1';
            }
            $sValue = '';
            foreach($aData as $key => $value)
            {
                $sValue = $sValue . "$key = '$value',";
            }
            $sValue = trim($sValue, ',');
            $sSql = "UPDATE $sTable SET $sValue WHERE $sCondition";
            $result = $this->execute($sSql);
            return $result;
        }

        /**
        *   FUNCTION get ARC2Store confige
        */
        public function getArc2Config()
        {
            $aConfig = array(
                /* db */
                'db_host' => $this->HOST, /* optional, default is localhost */
                'db_name' => $this->DATABASE,
                'db_user' => $this->USERNAME,
                'db_pwd' => $this->PASSWORD,

                /* store name */
                'store_name' => 'my_store',

                /* endpoint */
                'endpoint_features' => array(
                    'select', 'construct', 'ask', 'describe', 
                    'load', 'insert', 'delete', 
                    'dump' /* dump is a special command for streaming SPOG export */
                ),
                'endpoint_timeout' => 60, /* not implemented in ARC2 preview */
                'endpoint_read_key' => '', /* optional */
                'endpoint_write_key' => '', /* optional, but without one, everyone can write! */
                'endpoint_max_limit' => 250, /* optional */
            );

            return $aConfig;
        }

        /**
        *   FUNCTION CREATE resources rdf file and load to ARC2Store 
        */
        public function createResources($aNameSpace = array(), $aData = array(), $sId = '', $sType = '')
        {
            // Add namespace for rdf file
            $conf = array('ns' => $aNameSpace);
            $ser = ARC2::getRDFXMLSerializer($conf);
            if(empty($sType))
            {
                $uri = URL::getLink('id/'.$sId);
            }
            else
            {
                $uri = URL::getLink($sType."/id/". $sId);
            }

            // save file rdf
            $doc = $ser->getSerializedIndex($aData);
            $sFile = "data/".$sId.".rdf";
            $wfile = fopen($sFile,"w");
            fwrite($wfile,$doc);
            fclose($wfile);

            // local store
            $store = ARC2::getStoreEndpoint($this->getArc2Config());
            $store->query("LOAD <$uri>");
        }

        /**
        *    FUNCTION LOAD REMOVE QUERY
        */
        public function loadRemoteQuery($sEndPoint = '', $sQuery = '')
        {
            /* configuration */ 
            $config = array(
                /* remote endpoint */
                'remote_store_endpoint' => $sEndPoint,
            );
            /* instantiation */
            $store = ARC2::getRemoteStore($config);   
            $sQuery = preg_replace("/[\r\n\s]+/", " ", $sQuery);
            $rows = $store->query($sQuery, 'rows');
            return $rows;
        }

        /**
        *   FUNCTION LOAD query from ARC2Store 
        */

        public function loadQuery($sQuery = '')
        {
            // local store
            database::$iCountQuerySPARQL++;
            $store = ARC2::getStoreEndpoint($this->getArc2Config());
            $sQuery = preg_replace("/[\r\n\s]+/", " ", $sQuery);
            $aResult = $store->query($sQuery);
            if($aResult['query_type'] == 'delete')
            {
                return $aResult['result']['t_count'];
            }
            return $aResult;
        }

        /**
        *   FUNCTION update item 
        */
        public function updateResources($aNameSpace = array(), $aData = array(), $sId = '', $sType = '')
        {
            if(empty($sType))
            {
                $uri = URL::getLink("id/". $sId);
            }
            else
            {
                $uri = URL::getLink($sType."/id/". $sId);
            }
            $this->removeAllProperity($uri);
            $sQuery = "DELETE FROM <".$uri.">";
            $this->loadQuery($sQuery);
            $this->createResources($aNameSpace , $aData, $sId, $sType);
        }

        /**
        *   FUNCTION add properity to resources
        */
        public function addProperity($uri , $sProperity, $sValue)
        {
            $graph = new Graphite();
            $graph->ns('bus',URL::getLink("id/bussiness#"));
            $graph->load($uri );
            $graph->resource($uri)->add( $sProperity, $sValue );
            $doc = $graph->serialize();

            $aParams = explode('/',$uri);
            $sFile = "data/".end($aParams).".rdf";
            $wfile = fopen($sFile,"w");
            fwrite($wfile,$doc);
            fclose($wfile);

            // local store
            $this->removeAllProperity($uri);
            $sQuery = "DELETE FROM <".$uri.">";
            $this->loadQuery($sQuery);

            $store = ARC2::getStoreEndpoint($this->getArc2Config());
            $store->query("LOAD <$uri>");
        }

        /**
        *   FUNCTION add properity to resources
        */
        public function setProperity($uri , $sProperity, $sValue)
        {
            /* Hide error and message 
            ini_set('error_reporting', 0);
            ini_set('display_errors', 0);
            */
            $graph = new Graphite();
            $graph->ns('bus',URL::getLink("id/bussiness#"));
            $graph->load($uri );
            $bNew = false;
            if($graph->resource($uri)->has($sProperity))
            {
                $graph->resource($uri)->set($sProperity, $sValue );
            }
            else
            {
                $graph->resource($uri)->add($sProperity,$sValue);
                $bNew = true;
            }
            $doc = $graph->serialize();

            $aParams = explode('/',$uri);
            $sFile = 'data/'.end($aParams).'.rdf';
            $wfile = @fopen(trim($sFile),"w");
            if($wfile)
            {
                fwrite($wfile,$doc);
                fclose($wfile);
                // local store
                $this->removeAllProperity($uri);
                $sQuery = "DELETE FROM <".$uri.">";
                $result = $this->loadQuery($sQuery);
                if($result || $bNew)
                {
                    $result = $this->loadQuery("LOAD <$uri>");
                    return $result;
                }
                return false;
            }
            else
            {
                return false;
            }         
        }

        /**
        *   FUNCTION remove a properity from resource 
        */
        public function removeProperity($uri , $sProperity, $value = '')
        {
            $graph = new Graphite();
            $graph->ns('bus',URL::getLink("id/bussiness#"));
            $graph->load($uri );
            $graph->resource($uri)->remove( $sProperity ,$value);
            $doc = $graph->serialize();

            $aParams = explode('/',$uri);
            $sFile = "data/".end($aParams).".rdf";
            $wfile = fopen($sFile,"w");
            fwrite($wfile,$doc);
            fclose($wfile);

            // local store
            $this->removeAllProperity($uri);
            $sQuery = "DELETE FROM <".$uri.">";
            $this->loadQuery($sQuery);

            $store = ARC2::getStoreEndpoint($this->getArc2Config());
            $store->query("LOAD <$uri>");
        }

        /**
        *   DELETE PROPERITY OF URI 
        */
        public function removeAllProperity($uri)
        {
            $sQuery = "
            PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
            PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
            PREFIX bus: <".URL::getLink('id/bussiness#').">
            DELETE 
            {
            <".$uri."> ?p ?o ;
            }";
            $this->loadQuery($sQuery);
        }

        /**
        *   FUNCTION check admin User 
        */
        public static function isAdmin($bDirect = false)
        {
            core::checkSession();
            if(!database::isUser())
            {
                if($bDirect)
                {
                    header('location:'. URL::getLink());
                }
                else
                {
                    return false;
                }
            }
            $oDatabase = new database();
            $sQeury = "select type from user where user_id = '".$_SESSION['username']."'";
            $sType = $oDatabase->getValue($sQeury);
            if($sType == 'admin')
            {
                return true;
            }
            if($bDirect)
            {
                header('location:'. URL::getLink());
            }
            else
            {
                return false;
            }
        }

        /**
        *   FUNCTION check user login or guess 
        */
        public static function isUser($bDirect = false)
        {
            core::checkSession();
            if(isset($_SESSION['username']))
            {
                return true;
            }
            if($bDirect)
            {
                header('location:'. URL::getLink());
            }
            else
            {
                return false;
            }
        }

        /**
        *   FUNCTION DELETE DATA FROM STORE 
        */
        public function deleteFromStore($uri)
        {
            $sQuery = "DELETE FROM <".$uri.">";
            $this->loadQuery($sQuery);
            $sQuery = "
            PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
            PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
            PREFIX bus: <".URL::getLink("id/bussiness#").">
            DELETE 
            {
            <".$uri."> ?p ?o;
            }";
            $this->loadQuery($sQuery);
        }
        /**
        *   FUNCTION DELETE RDF FILE 
        */
        public function deleteResources($uri)
        {
            $aParams = explode('/',$uri);
            $sFile = "data/".end($aParams).".rdf";
            unlink($sFile);
            // local store
            $this->deleteFromStore($uri);
        }

        /**
        *   RESTORE DATABASE FROM RDF FILE 
        */
        public static function restoreDataBaseFromFile()
        {
            if ($handle = opendir('data')) {
                echo "Directory handle: $handle\n";
                echo "Entries:\n";
                echo '<br>';

                /* This is the correct way to loop over the directory. */
                while (false !== ($entry = readdir($handle))) {
                    echo "$entry\n";
                    echo '<br>';
                }
                closedir($handle);
            }
        }

        /**
        *   FUNCTION LOG 
        */
        public static function log($str = '')
        {
            $file = fopen("changelog/log.txt","a");
            fwrite($file,$str."\n");
            fclose($file);
        }

        /**
        *   FUNCTION ADD SETTING 
        */
        public static function setSetting($sSettingId, $sSettingValue, $sSettingKey = '',$sSettingType = '', $sSettingDescription = '')
        {
            $oDatabse = new database();
            $sQuery = "SELECT * FROM settings WHERE setting_id = '".$sSettingId."'";
            $result = $oDatabse->getListObject($sQuery);
            if(count($result) > 0)
            {
                $sQuery = "UPDATE settings SET setting_value = '".$sSettingValue."' ";
                if($sSettingKey != '')
                {
                    $sQuery = $sQuery. ",setting_key = '".$sSettingKey."' ";
                }
                if($sSettingKey != '')
                {
                    $sQuery = $sQuery. ",type = '".$sSettingType."' ";
                }
                if($sSettingKey != '')
                {
                    $sQuery = $sQuery. ",description = '".$sSettingDescription."' ";
                }
                $sQuery = $sQuery. "WHERE setting_id = '".$sSettingId."'";
                return $oDatabse->execute($sQuery);
            }
            else
            {
                $sQuery = "INSERT INTO settings VALUES('".$sSettingId."','".$sSettingKey."','".$sSettingValue."','".$sSettingType."','".$sSettingDescription."')";
                return $oDatabse->execute($sQuery);
            }
        }

        public static function getSetting($sSettingId)
        {
            $oDatabase = new database();
            $sQuery = "SELECT * FROM settings WHERE setting_id = '".$sSettingId."'";
            return $oDatabase->getObject($sQuery);
        }

        public static function getListSettings($sType)
        {
            $oDatabase = new database();
            $sQuery = "SELECT * FROM settings WHERE type = '".$sType."'";
            return $oDatabase->getListObject($sQuery,true,true);
        }

        public static function printVar($var)
        {
            echo '<textarea>';
            print_r($var);
            echo '</textarea>';
        }
    }

?>
